package concurrencyCookBook.phaser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;

/**
 * 
 * http://whitesock.iteye.com/blog/1135457 Phaser: 同步线程数
 * 
 * http://blog.csdn.net/andycpp/article/details/8838820
 */
public class PhaserDemo {

	public static void main(String[] args) throws InterruptedException,
			Exception {
		t2();
	}

	public static void t2() {
		final Phaser phaser = new Phaser(1);
		Thread thread = new Thread() {

			@Override
			public void run() {
				phaser.awaitAdvance(0);
				System.out
						.println("如果传入阶段数和当前阶段数一致这个方法将当前线程置于休眠,直到这个阶段的所有参与者都运行完成,如果不一致则马上返回");
				System.out.println("这个线程不统计数量");
			}

		};
		thread.start();
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		phaser.arriveAndAwaitAdvance();
	}

	public static void t1() throws IOException {
		final Phaser phaser = new Phaser(1);
		for (int i = 0; i < 5; i++) {
			phaser.register();
			System.out.println("starting thread, id: " + i);
			final Thread thread = new Thread(new Task(i, phaser));
			thread.start();
		}

		System.out.println("Press ENTER to continue");
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				System.in));
		reader.readLine();
		phaser.arriveAndDeregister();
	}

	public static class Task implements Runnable {
		private final int id;
		private final Phaser phaser;

		public Task(int id, Phaser phaser) {
			this.id = id;
			this.phaser = phaser;
		}

		@Override
		public void run() {
			System.out.println(phaser.getPhase() + ":getPhase表示第几轮");
			if (this.id == 3) {
				phaser.arrive();
				System.out.println("标记到达,但不等待其他线程就执行下面的代码了");
			} else if (this.id == 2) {
				phaser.arriveAndDeregister();
				System.out.println("标记到达,不等待其他线程,并且注销自己");
			} else {
				// 方法用于记录到达，并且等待其它未到达的任务
				phaser.arriveAndAwaitAdvance();
			}
			System.out.println("in Task.run(), phase: " + phaser.getPhase()
					+ ", id: " + this.id);
		}
	}

}
